package lambdasinaction.chap5.my;

import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
import lambdasinaction.chap4.MyDish;

/**
 * TODO
 *
 * @author Fish
 * @since 0.0.1 2018/7/24 12:08
 */
public class MyFiltering {

  public static void main(String[] args) {
    /**
     * Streams接口支持filter 方法。该操作会接受一个谓词（一个返回 boolean的函数）作为参数，
     * 并返回一个包括所有符合谓词的元素的流
     * 方法引用检查菜肴是否适合素食者
     */
    List<MyDish> vegetarianMenu = MyDish.menu.stream().filter(MyDish::isVegetarian)
        .collect(Collectors.toList());
    vegetarianMenu.forEach(System.out::println);

    /**
     * 筛选各异的元素
     * 流还支持一个叫做distinct的方法，它会返回一个元素各异（根据流所生成元素的hashCode和 equals方法实现）的流
     * 例如，以下代码会筛选出列表中所有的偶数，并确保没有重复
     */
    List<Integer> numbers = Arrays.asList(1, 2, 1, 1, 3, 3, 2, 4);
    numbers.stream().filter(n -> n % 2 == 0).distinct().forEach(System.out::println);

    /**
     * 截断流
     * 刘支持 limit(n) 方法，该方法会返回一个不超过给定长度的流。所需的长度作为参数传递给limit
     * 如果流是有序的，则最多返回前 n个元素。比如，你可以建立一个 list，选出热量超过300卡路里的头三道菜
     */
    List<MyDish> dishesLimit3 = MyDish.menu.stream().filter(d -> d.getCalories() > 300).limit(3)
        .collect(Collectors.toList());
    dishesLimit3.forEach(System.out::println);

    System.out.println("---skip---");

    /**
     * 跳过元素
     * 流还支持 skip(n)方法，返回一个扔掉了前n 个元素的流。如果流中元素不足 n个，则返回一个空流
     * 请注意 limit(n) 和 skip(n)是互补的！例如，下面的代码将跳过超过300卡路里的头两道菜。并返回剩下的
     */
    List<MyDish> dishesSkip2 = MyDish.menu.stream().filter(d -> d.getCalories() > 300).limit(3).skip(2).collect(Collectors.toList());
    dishesSkip2.forEach(System.out::println);
  }

}
